import { Injectable, BadRequestException, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from './schemas/user.schema';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcryptjs';
import { MailService } from '../mail/mail.service';
import { VerificationService } from '../verification/verification.service';
import { CreateUserDto } from './dto/create-user.dto';
import { LoginDto } from './dto/login.dto';

@Injectable()
export class UserService {
  constructor(
    @InjectModel(User.name) private userModel: Model<User>,
    private readonly jwtService: JwtService,
    private readonly mailService: MailService,
    private readonly verificationService: VerificationService,
  ) { }

  async register(createUserDto: CreateUserDto) {
    const { email, password, code } = createUserDto;

    // 验证验证码
    // const isCodeValid = await this.verificationService.verifyCode(email, code);
    // if (!isCodeValid) {
    //   throw new BadRequestException('验证码无效或已过期');
    // }

    // 检查用户是否已存在
    const existingUser = await this.userModel.findOne({ email });
    if (existingUser) {
      throw new BadRequestException('该邮箱已被注册');
    }

    // 加密密码
    const hashedPassword = await bcrypt.hash(password, 10);

    // 创建新用户
    const user = await this.userModel.create({
      email,
      password: hashedPassword,
      isActive: true,
      coins: 0,
      isAdmin: false,
    });

    return this.generateToken(user);
  }

  async login(loginDto: LoginDto) {
    const { email, password } = loginDto;
    const user = await this.userModel.findOne({ email });

    if (!user) {
      throw new UnauthorizedException('用户不存在');
    }

    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      throw new UnauthorizedException('密码错误');
    }

    return this.generateToken(user);
  }

  async findById(id: string) {
    const user = await this.userModel.findById(id).select('-password');
    if (!user) {
      throw new BadRequestException('用户不存在');
    }
    return user;
  }

  async sendVerificationCode(email: string) {
    const code = await this.verificationService.generateAndStoreCode(email);
    await this.mailService.sendVerificationCode(email, code);
  }

  async resetPassword(token: string, newPassword: string) {
    try {
      const payload = this.jwtService.verify(token);
      const user = await this.userModel.findById(payload.sub);

      if (!user) {
        throw new BadRequestException('用户不存在');
      }

      const hashedPassword = await bcrypt.hash(newPassword, 10);
      user.password = hashedPassword;
      await user.save();
    } catch (error) {
      throw new BadRequestException('重置令牌无效或已过期');
    }
  }

  private generateToken(user: User) {
    const payload = { sub: user._id, email: user.email };
    return {
      access_token: this.jwtService.sign(payload),
      user: {
        id: user._id,
        email: user.email,
        isAdmin: user.isAdmin,
        isActive: user.isActive,
        coins: user.coins,
      },
    };
  }

  async forgetPassword(email: string): Promise<void> {
    const user = await this.userModel.findOne({ email });
    if (!user) {
      throw new BadRequestException('用户不存在');
    }

    // 生成重置令牌
    const resetToken = this.jwtService.sign(
      { userId: user._id },
      { expiresIn: '1h' }
    );

    // 发送重置密码邮件
    await this.mailService.sendPasswordReset(email, resetToken);
  }

  async addCoins(userId: string, amount: number) {
    const user = await this.userModel.findById(userId);
    if (!user) {
      throw new NotFoundException('User not found');
    }

    user.coins += amount;
    await user.save();
    return user;
  }

  async findByEmail(email: string) {
    return await this.userModel.findOne({ email });
  }
} 